package com.emergency.embackend.service.impl;

import com.emergency.embackend.common.PageParams;
import com.emergency.embackend.entity.QuizSuit;
import com.emergency.embackend.entity.QuizSuitData;
import com.emergency.embackend.mapper.QuizDataMapper;
import com.emergency.embackend.mapper.QuizHistoryMapper;
import com.emergency.embackend.mapper.QuizSuitDataMapper;
import com.emergency.embackend.mapper.QuizSuitMapper;
import com.emergency.embackend.param.AddQuizSuitParam;
import com.emergency.embackend.param.QuizSuitParam;
import com.emergency.embackend.service.QuizSuitService;
import com.emergency.embackend.utils.RandomIdUtils;
import com.emergency.embackend.utils.RecommendUtils;
import com.emergency.embackend.utils.UserHolder;
import com.emergency.embackend.vo.QuizSortVO;
import com.emergency.embackend.vo.QuizSuitVO;
import com.emergency.embackend.vo.UserSuitRecordVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import sun.security.pkcs11.wrapper.CK_SSL3_RANDOM_DATA;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author chddd
 * @description
 * @create 2024/3/11 17:06:05
 */
@Service
public class QuizSuitServiceImpl implements QuizSuitService {
    @Autowired
    private QuizSuitMapper quizSuitMapper;
    @Autowired
    private QuizDataMapper quizDataMapper;
    @Autowired
    private QuizHistoryMapper quizHistoryMapper;
    @Autowired
    private QuizSuitDataMapper quizSuitDataMapper;

    @Override
    public PageInfo page(QuizSuitParam quizSuitParam) {
        PageHelper.startPage(quizSuitParam.getPageNum(), quizSuitParam.getPageSize());
        List<QuizSuitVO> resList = quizSuitMapper.page(quizSuitParam);
        PageInfo pageInfo = new PageInfo(resList);
        return pageInfo;
    }

    @Override
    public void delete(Long quizSuitId) {
        quizSuitMapper.delete(quizSuitId);
    }

    @Override
    public Long add(AddQuizSuitParam addQuizSuitParam) {
        QuizSuit quizSuit = new QuizSuit();
        BeanUtils.copyProperties(addQuizSuitParam, quizSuit);
        quizSuit.setCreateTime(new Date());
        //插入套题库
        quizSuitMapper.add(quizSuit);
        //插入中间表
        List<QuizSuitData> quizSuitDatas = new ArrayList<>();
        addQuizSuitParam.getQuizIdList().forEach(e -> {
            QuizSuitData quizSuitData = new QuizSuitData();
            quizSuitData.setQuizDataId(e);
            quizSuitData.setQuizSuitId(quizSuit.getQuizSuitId());
            quizSuitDatas.add(quizSuitData);
        });
        quizSuitDataMapper.add(quizSuitDatas);
        return quizSuit.getQuizSuitId();
    }

    @Override
    public void update(AddQuizSuitParam addQuizSuitParam) {
        //删掉中间表数据
        quizSuitDataMapper.deleteByQuizSuitId(addQuizSuitParam.getQuizSuitId());
        //修改套题
        QuizSuit quizSuit = new QuizSuit();
        BeanUtils.copyProperties(addQuizSuitParam, quizSuit);
        quizSuitMapper.update(quizSuit);
        //插入套题库
        List<QuizSuitData> quizSuitDatas = new ArrayList<>();
        addQuizSuitParam.getQuizIdList().forEach(e -> {
            QuizSuitData quizSuitData = new QuizSuitData();
            quizSuitData.setQuizDataId(e);
            quizSuitData.setQuizSuitId(addQuizSuitParam.getQuizSuitId());
            quizSuitDatas.add(quizSuitData);
        });
        quizSuitDataMapper.add(quizSuitDatas);
    }

    @Override
    public UserSuitRecordVO getUserSuitRecord(QuizSuitParam quizSuitParam, Long userId) {
        List<QuizSuitVO> userPassHistory = quizHistoryMapper.getUserPassHistory(quizSuitParam, userId);
        List<QuizSuitVO> unPassHistory = quizHistoryMapper.getUnPassHistory(quizSuitParam, userId);
        UserSuitRecordVO userSuitRecordVO = new UserSuitRecordVO();
        int totalSuit = 0;
        Set<Long> set = new HashSet<>();
        if ((userPassHistory != null && userPassHistory.size() != 0)) {
            set.addAll(userPassHistory.stream().map(QuizSuitVO::getQuizSuitId).collect(Collectors.toSet()));
            userSuitRecordVO.setPassList(userPassHistory);
            userSuitRecordVO.setCompleteQuantity(Long.valueOf(userPassHistory.size()));
            totalSuit += userPassHistory.size();
        }
        if (unPassHistory != null && unPassHistory.size() != 0) {
            set.addAll(unPassHistory.stream().map(QuizSuitVO::getQuizSuitId).collect(Collectors.toSet()));
            userSuitRecordVO.setUnPassList(unPassHistory);
            userSuitRecordVO.setUnPassQuantity(Long.valueOf(unPassHistory.size()));
            totalSuit += unPassHistory.size();
        }
        //判断没有做过的
        List<QuizSuitVO> undoSuit = quizSuitMapper.getUndoSuit(quizSuitParam, set);
        if (undoSuit != null && undoSuit.size() != 0) {
            userSuitRecordVO.setUnDoList(undoSuit);
            userSuitRecordVO.setUnDoQuantity(Long.valueOf(undoSuit.size()));
            totalSuit += undoSuit.size();
        }
        userSuitRecordVO.setTotalSuit(Long.valueOf(totalSuit));
        return userSuitRecordVO;
    }

    @Override
    public PageInfo getRecentlySuit(PageParams pageParams) {
        PageHelper.startPage(pageParams.getPageNum(), pageParams.getPageSize());
        List<QuizSuit> recentlySuit = quizSuitMapper.getRecentlySuit();
        PageInfo quizSuitPageInfo = new PageInfo(recentlySuit);
        return quizSuitPageInfo;
    }

    @Override
    public List<QuizSuitVO> getRecommendSuit(QuizSuitParam quizSuitParam) {
        Long userId = UserHolder.getUser().getId();
        Set<Long> set = new HashSet<>();
        List<QuizSuitVO> userPassHistory = quizHistoryMapper.getUserPassHistory(quizSuitParam, userId);
        List<QuizSuitVO> unPassHistory = quizHistoryMapper.getUnPassHistory(quizSuitParam, userId);
        List<QuizSuitVO> resList = new ArrayList<>(10);

        if (userPassHistory != null && userPassHistory.size() != 0) {
            set.addAll(userPassHistory.stream().map(QuizSuitVO::getQuizSuitId).collect(Collectors.toSet()));
        }
        if (unPassHistory != null && unPassHistory.size() != 0) {
            set.addAll(unPassHistory.stream().map(QuizSuitVO::getQuizSuitId).collect(Collectors.toSet()));
        }
        List<QuizSuitVO> undoSuit = quizSuitMapper.getUndoSuit(quizSuitParam, set);
        //如果有存在未做的题目，则推荐未做的题目
        if (undoSuit != null && undoSuit.size() != 0) {
            getRecommendSuit(undoSuit, resList);
        }
        if(unPassHistory !=null && unPassHistory.size()!=0){
            getRecommendSuit(unPassHistory,resList);
        }
        //则从未通过的题目中去获取
        //如果都未满足，就从所有题库中随机抽取
        if(userPassHistory !=null && userPassHistory.size()!=0){
            getRecommendSuit(userPassHistory,resList);
        }
        if(quizSuitParam.getLimitNum()!=null){
            return resList.subList(0,quizSuitParam.getLimitNum().intValue());
        }
        return resList;
    }

    private void getRecommendSuit(List<QuizSuitVO> quizSuit, List<QuizSuitVO> resList) {
        //随机抽取 做一个随机数抽取
        List<Long> randomIds = RandomIdUtils.getRandomNum(quizSuit.stream()
                .map(QuizSuitVO::getQuizSuitId)
                .collect(Collectors.toList()));
        Map<Long, QuizSuitVO> map = new HashMap<>(quizSuit.size());
        quizSuit.forEach(e -> {
                    map.put(e.getQuizSuitId(), e);
                });
        randomIds.forEach(id->{
            resList.add(map.get(id));
        });
    }
}
